/*
 * @Author: your name
 * @Date: 2021-12-30 19:22:02
 * @LastEditTime: 2021-12-30 20:03:04
 * @LastEditors: Please set LastEditors
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: \flutter-learning\Dart_Basic_Grammer\generic_genericClass.dart
 */

/**
 * 泛型：通俗理解，泛型就是解决 类 接口 方法的复用性，以及对不特定数据类型的支持（类型校验）
 */

// 方法传入什么类型就返回什么类型
T getData<T>(T value) {
  return value;
}

// 普通类：此时只能增加 int 类型的 value
class MyList {
  List list = <int>[];
  void add(int value) {
    this.list.add(value);
  }
  List getList() {
    return list;
  }
}

// 泛型类：想要同时增加 int 类型的 value 和 String 类型的 value，并且完成类型校验
class MyListT<T> {
  List list = <T>[];
  void add(T value) {
    this.list.add(value);
  }
  List getList() {
    return list;
  }
}

/**
 * 泛型接口：
 *    实现数据缓存的功能，有文件缓存和内存缓存，内存话黁和文件缓存按照接口的约束实现
 *      1. 定义一个泛型接口 约束实现他的子类必须由 getByKey(key) 和 setByKey(key, value)
 *      2. 要求 setBy Key 的时候的 value 的类型和实例化子类的时候指定的类型一致
 */

abstract class ObjectCache {
  getByKey(String key);
  void setByKey(String key, String value);
}

abstract class StringCache {
  getByKey(String key);
  void setByKey(String key, String value);
}

abstract class Cache<T> {
  getByKey(String key);
  void setByKey(String key, T value);
}

class FileCache<T> implements Cache<T> {
  @override
  getByKey(String key) {
      // TODO: implement getByKey
    }
  
  @override
  void setByKey(String key, T value) {
    // TODO: implement setByKey
    print("File");
  }
  
}

class MemoryCache<T> implements Cache<T> {
  @override
  getByKey(String key) {
      // TODO: implement getByKey
    }
  
  @override
  void setByKey(String key, T value) {
    // TODO: implement setByKey
    print("Memory");
  }
  
}

void main(List<String> args) {
  getData<String>("hello");
  getData<int>(12);
  
  // 泛型类
  List list1 = new List<int>.filled(2, 0);
  list1[0] = 2;
  list1[1] = 3;
  print(list1);

  MyList l = MyList();
  l.add(1);
  l.add(2);
  print(l.getList());

  // 泛型类实例化
  MyListT l1 = new MyListT();
  l1.add(12);
  l1.add("hello");

  MyListT l2 = new MyListT<int>();
  l2.add("hello");

  // 泛型接口
  MemoryCache m = new MemoryCache<String>();
  m.setByKey("index", "hello");

  FileCache f = new FileCache<int>();
  f.setByKey("hh", 2);

}